use std::fmt::{Display, Formatter};
use std::fs::OpenOptions;
use std::io::{Read, Write};

use anyhow::{anyhow, Result};

use crate::{error, success, APP_CONFIG};
pub use plugin::{Plugin, PluginScript};
pub use cli::*;
pub use server::*;
pub use work::WorkUtil;

mod work;
mod server;
mod plugin;
mod cli;

#[derive(Debug, Serialize, Deserialize)]
pub struct AppData {
    pub servers: Vec<ServerItem>,
}
impl Display for AppData {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", serde_json::to_string(&self.servers).expect("数据格式化错误！"))
    }
}

impl AppData {
    pub fn read_data() -> Result<Self> {
        let app_config = APP_CONFIG.get().unwrap_or_else(|| panic!("获取配置失败！"));
        let data_path = app_config.database.as_ref().unwrap_or_else(|| panic!("获取数据文件路径失败！"));
        let mut app = AppData { servers: vec![] };
        if data_path.exists() {
            let mut fs = OpenOptions::new().read(true).open(data_path)?;
            let mut data = vec![];
            let len = fs.read_to_end(&mut data)?;
            if len > 0 {
                data = crate::utils::aes256_cbc_decrypt(&data).unwrap();
                app = bincode::deserialize(&data).unwrap_or_else(|_| { AppData { servers: vec![] } });
            }
        }
        Ok(app)
    }

    pub fn write_data(&self) -> Result<()> {
        let app_config = APP_CONFIG.get().unwrap_or_else(|| panic!("获取配置失败！"));
        let data_path = app_config.database.as_ref().unwrap_or_else(|| panic!("获取数据文件路径失败！"));
        let mut encoded = bincode::serialize(self)?;
        encoded = crate::utils::aes256_cbc_encrypt(&encoded).unwrap();
        if let Ok(mut fs) = OpenOptions::new().write(true).create(true).truncate(true).open(data_path) {
            fs.write_all(&encoded)?;
        }
        Ok(())
    }

    pub fn get_server(&self, label: String) -> Result<&ServerItem> {
        if let Some(item) = self.servers.iter().find(|it| it.label.eq(&label)) {
            Ok(item)
        } else {
            Err(anyhow!("{} 服务器不存在！", label))
        }
    }

    pub fn update_server(&mut self, server: ServerItem) -> Result<()> {
        if let Some(index) = self.servers.iter().position(|item| item.label.eq(&server.label)) {
            self.servers[index] = server;
            self.write_data()?;
        }
        Ok(())
    }

    pub fn add_server(&mut self, server: ServerItem) -> Result<()> {
        self.servers.push(server);
        self.write_data()?;
        success("新增成功！");
        Ok(())
    }

    pub fn del_server(&mut self, label: String) -> Result<()> {
        if self.servers.iter().any(|it| it.label.eq(&label)) {
            self.servers.retain(|x| x.label.ne(&label));
            self.write_data()?;
            success("删除成功！");
        } else {
            error(format!("{} 服务器不存在！", label));
        }
        Ok(())
    }
}